home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / dirutl / tree.arc / TREE.ASM next >
Assembly Source File  |  1986-08-27  |  14KB  |  535 lines

  1. ; tree.asm    g.r.green
  2. ; program to draw directory tree of the default drive 
  3. ; running msdos.
  4. ; changes made to accomodate for the IBM line drawing set 
  5. ; Hans ZURFCC::Zangger Aug 86 {Baum == german for 'tree'
  6. ;
  7. ;        TREE.ASM Copyright (C) by Gordon R. Green
  8. ;               9-May-1985 All Rights Reserved. Released For Any
  9. ;               use without cost exceeding the cost of handling
  10. ;               and reproduction, as long this heading is
  11. ;               included with all or any part used of this
  12. ;               program and credit given to Gordon R. Green.
  13. ;
  14. ;                Gordon R. Green
  15. ;            7 Juniper St.
  16. ;            Hudson, N.H. 03051
  17. ;
  18. ;
  19. ; Installation Instructions:
  20. ;    masm tree
  21. ;    link tree        ; ignore lack of stack err msg!!!
  22. ;    exe2bin tree.exe tree.com
  23. ;    del tree.exe
  24. ;
  25. ; Invocation:
  26. ;    TREE            ; takes no arguments
  27.  
  28.  
  29. ;**************************************************************
  30. ; Macro definitions
  31.  
  32. ;    DISPLAY STRING
  33. display    macro    string
  34.     mov    dx,offset string
  35.     mov    ah,9
  36.     int    doscall
  37.     endm
  38.  
  39. ;    SET_DTA
  40. set_dta    macro    buffer
  41.     mov    dx,offset buffer
  42.     mov    ah,1AH
  43.     int    doscall
  44.     endm
  45.  
  46. ;    SEARCH_FIRST
  47. search_first    macro    fcb
  48.     mov    dx,offset fcb
  49.     mov    ah,11H
  50.     int    doscall
  51.     endm
  52. ;
  53. FSCROLL     EQU    6        ;BIOS function = scroll
  54. FLOCATE     EQU    2        ;BIOS function = locate
  55. COLOR        EQU    7        ;attribute, white on black background
  56. ALL        EQU    0        ;indicates entire screen on scroll
  57. HOR             EQU     196
  58. VER             EQU     179
  59. COR             EQU     192
  60. LFIN            EQU     195
  61. TFIN            EQU     194
  62. BFIN            EQU     192
  63. FACE            EQU     1
  64. ;
  65. BIOSCAL MACRO    FUNCTION
  66.     MOV    AH,FUNCTION             ;specify function desired
  67.     INT    10H                     ;call BIOS for desired function
  68. ENDM
  69. ;
  70.  
  71. SCROLL    MACRO    POS1,POS2,ATTRIBUTE,ROWS
  72. ;;coordinates to be presented in row,col format as a single number, as:
  73. ;;row * 256 + col
  74. ;;
  75. ;;POS1      =upper left coordinate
  76. ;;POS2      =lower right coordinate
  77. ;;ATTRIBUTE =color descriptor of fill character
  78. ;;ROWS      =how many rows to be scrolled (0=do entire screen)
  79.                                         
  80.     MOV    CX,POS1                 ;upper left corner
  81.     MOV    DX,POS2                 ;botton right corner
  82.     MOV    BH,ATTRIBUTE            ;pass how to color fill
  83.     MOV    AL,ROWS                 ;do entire window
  84.     BIOSCAL FSCROLL                 ;request scroll function from bios
  85. ENDM
  86. ;
  87. LOCATE    MACRO    ROW,COL
  88.     MOV    DH,ROW                  ;move cursor to this row
  89.     MOV    DL,COL                  ;and to this col in this screen number
  90.     MOV    BH,0
  91.     BIOSCAL FLOCATE                 ;move cursor
  92. ENDM
  93. ;
  94. ; End of macros
  95. ;**************************************************************
  96.  
  97.  
  98. ;**************************
  99. ;***            ***
  100. ;***    EQU Statements    ***
  101. ;***            ***
  102. ;**************************
  103.  
  104. max_level    equ    14
  105. doscall        equ    21H
  106.  
  107. ; dos calls
  108. type_chr    equ    2
  109. find_file    equ    4EH
  110. find_nxt_file    equ    4FH
  111.  
  112. ; ASCII characters
  113. CR        equ    0DH
  114. LF        equ    0AH
  115. H_TAB        equ    9
  116.  
  117.  
  118. ;**************************
  119. ;***            ***
  120. ;***    Main Program    ***
  121. ;***            ***
  122. ;**************************
  123.  
  124. ;***********************************************************
  125. prognam    segment    ;define code segment
  126.  
  127.     org    100H
  128.  
  129.     assume cs:prognam, ds:prognam, ss:prognam
  130.  
  131. start:
  132.     push    ds            ; set up return to DOS
  133.     call    crlf
  134.     xor    ax,ax            ; clear ax
  135.     push    ax
  136.     call    init            ; init tables, save current directory,
  137.                     ;   switch to root
  138. ; read disk name and display it
  139.  
  140.     set_dta    buffer
  141.     search_first    fcb        ; look for disk name
  142.     cmp    al,0FFH            ; found?
  143.     jne    name_fnd        ; if yes
  144. ;       mov     al," "                  ; else fill in blank name
  145. ;display hig_vid
  146. display no_label                        ; else say No Label
  147. jmp nolabel
  148.         mov     di,offset buffer+8
  149.     mov    cx,11
  150.     repz    stosb
  151. name_fnd:
  152.     mov    al,"$"            ; insert string terminator
  153.     mov    buffer[19],al
  154. ;display hig_vid
  155. ;display spaces1
  156.         display buffer[8]               ; display name in reverse video
  157. nolabel:
  158. ;display reg_vid
  159.     display    link            ; draw lines down to main tree
  160.     mov    unused,3        ; force proper positioning later
  161.  
  162. ; read root directory into memory and sort it
  163.     mov    di,offset buf        ; pntr to filename storage
  164.     mov    begin_dir,di
  165.     call    get_file_names        ; get filenames for this level
  166.     mov    bx,level
  167.     mov    begin_dir[bx+2],di    ; mark start of next level
  168.     mov    num_dir[bx],ax        ; save # of directories at this level
  169.     cmp    ax,0            ; any sub-diretories?
  170.         je      no_sub_dirs             ;   if none in root, then no tree
  171.  
  172. main_loop:
  173.     mov    bx,level        ; all dirs done at this level?
  174.     mov    ax,cur_dir[bx]
  175.     cmp    ax,num_dir[bx]
  176.     jne    more_dirs        ; if not
  177.     cmp    bx,0            ; are we at top level?
  178.     jne    up            ; if no
  179. abort:  jmp     quit                    ; if yes
  180. more_dirs:
  181.     call    dn_level        ; go down one level
  182.     mov    bx,level        ; init di with where to store filenames
  183.     mov    di,begin_dir[bx]
  184.     call    get_file_names
  185.     mov    bx,level        ; save pntr for next level
  186.     mov    begin_dir[bx+2],di
  187.     mov    num_dir[bx],ax        ; save # dirs at this level
  188.     mov    cur_dir[bx],0        ; set cur_dir=0 for this level
  189.     cmp    ax,0            ; any dirs?
  190.     jne    more_dirs        ; if yes, go dn another level
  191.     call    crlf
  192.     mov    unused,-1
  193. up:
  194.     call    up_level        ; else go up a level
  195.     mov    bx,level        ;   bump cnt of cur_dir
  196.     inc    cur_dir[bx]
  197.     jmp    main_loop        ;   and loop back
  198. quit:
  199.     call    crlf
  200.     mov    ah,3BH            ; restore original directory
  201.     mov    dx,offset old_dir
  202.     int    doscall
  203.     ret                ; exit to dos
  204.  
  205. no_sub_dirs:
  206.         display no_subdirs
  207.         jmp quit
  208.  
  209. ;**********************************
  210. ;***                ***
  211. ;***    Support Routines    ***
  212. ;***                ***
  213. ;**********************************
  214.  
  215. ;**************************************************************
  216. ; initialize a bunch of things
  217. ;    on entry ax = 0
  218. init:
  219. ; init tables (begin_dir, num_dir, cur_dir)
  220.     mov    di,offset begin_dir    ; (ax = 0)
  221.     mov    cx,max_level * 3
  222.     repz    stosw
  223.     mov    level,ax        ; (ax = 0)
  224.  
  225. ; init default file spec at 5CH
  226.     mov    al,"?"            ; fill with wildcards
  227.     mov    di,byte ptr 5DH        ;    default fcb+1
  228.     mov    cx,11
  229.     repz    stosb
  230.  
  231. ; save current directory name
  232.     mov    ah,47H            ; get current directory name
  233.     mov    si,offset old_dir+1    ;    and put here
  234.     mov    dl,0            ;    from present drive
  235.     int    doscall
  236.  
  237. ; change to root_directory
  238.     mov    ah,3BH            ; change current directory
  239.     mov    dx,offset root_dir    ;    to root-directory
  240.     int    doscall
  241.         scroll    0,24*256+79,color,all    ; scroll row=24, col=79 (zero relative)
  242.         locate    0,0            ;Cursor to top left at (0,0)
  243.         locate  0,65
  244.     display    sign_on            
  245.         locate  0,0
  246.     ret                ;   escape sequence
  247.  
  248.  
  249. ;**************************************************************
  250. ; move down a directory level
  251.  
  252. dn_level:
  253. ; move to new directory
  254.     mov    bx,level
  255.     mov    si,begin_dir[bx]    ; where names start for this level
  256.     mov    ax,cur_dir[bx]        ; cur_dir
  257.     mov    cx,11
  258.     mul    cl            ; times size = offset
  259.     add    ax,si            ; ax points to next name
  260.     mov    si,ax            ; move to si
  261.     mov    di,offset dn_dir + 2
  262.     mov    cx,8            ; ready to move 8 chars
  263.     repz    movsb
  264.     call    show_name        ; display the directory name
  265.     mov    ah,3BH            ; change current directory
  266.     mov    dx,offset dn_dir
  267.     cmp    level,0
  268.     jne    dn_lv
  269.     inc    dx
  270. dn_lv:
  271.     int    doscall            ;### error chk?
  272.     inc    level            ; adjust level count
  273.     inc    level            ;    by 2
  274.     ret
  275.  
  276.  
  277. ;**************************************************************
  278. ; show directory name
  279.  
  280. show_name:
  281.     cmp    unused,-1        ; new line?
  282.     jne    shnm0            ;   if not
  283.     call    do_indents
  284.     mov    unused,0
  285. shnm0:    mov    cx,unused        ; any unused?
  286.     cmp    cx,0            ;   if not
  287.     je    shnm2
  288. shnm1:  mov     dl, HOR                 ;   else pad with hor lines
  289.     mov    ah,2
  290.     int    doscall
  291.     loop    shnm1
  292. shnm2:    mov    bx,level
  293.         mov     end_pad, LFIN           ; init end_pad to left "T"
  294.         cmp     cur_dir [bx],0          ; determine end_pad value
  295.     jne    shnm3
  296.         mov     end_pad, TFIN           ; if 1st, top "T"
  297. shnm3:  mov     ax,cur_dir [bx]
  298.         inc     ax
  299.         cmp     ax,num_dir [bx]
  300.     jne    shnm4
  301.         mov     end_pad, BFIN            ; if last, lower left corner
  302. shnm4:    dec    ax
  303.     cmp    ax,0
  304.     jne    shnm5
  305.     cmp    num_dir[bx],1
  306.     jg    shnm5
  307.         mov     end_pad, HOR             ; if 1st & last, horizontal line
  308. shnm5:    mov    dl,end_pad        ; output end_pad
  309.     mov    ah,2
  310.     int    doscall
  311. ;display spaces1
  312. ;display hig_vid                 ; switch to reverse video
  313.     mov    bx,offset dn_dir + 2    ; output name
  314.     mov    dl,[bx]            ;   first character
  315.     mov    ah,2
  316.     int    doscall
  317.     inc    bx
  318.     mov    cx,7            ; 7 more characters in filename
  319. shnm6:    mov    dl,[bx]            ; all but first char in lower case
  320.     cmp    dl,0
  321.     je    shnm8            ; if nul
  322.     cmp    dl,"A"
  323.     jl    shnm7
  324.     cmp    dl,"Z"
  325. ;       jg      shnm7
  326. ;       or      dl," "
  327. shnm7:    mov    ah,2            ; finally output char
  328.     int    doscall
  329.     inc    bx
  330.     loop    shnm6            ; loop for all chars
  331. shnm8:    mov    unused,cx
  332. ;display spaces1
  333. ;display reg_vid                 ; back to normal video
  334.     ret
  335.  
  336.  
  337. ;**************************************************************
  338. ; handle the indents at beginning of line
  339.  
  340. do_indents:
  341.         mov     bx,0                    ; "level" for this routine
  342. do_ind1:
  343.     display    spaces8            ; output leading spaces8
  344.     cmp    bx,level        ; done if present level
  345.     je    do_ind3
  346.     mov    dl," "            ;   else output space
  347.         mov     ax,cur_dir [bx]
  348.     inc    ax
  349.         cmp     ax,num_dir [bx]
  350.     je    do_ind2
  351. ;display spaces1
  352.         mov     dl, VER                  ;   or vertical bar
  353. do_ind2:
  354.     mov    ah,2
  355.     int    doscall
  356. do_ind3:
  357.     inc    bx            ; bump local index
  358.     inc    bx
  359.     cmp    bx,level        ; see if we are done
  360.     jle    do_ind1            ;    if not
  361.     ret
  362.  
  363. ;**************************************************************
  364. ; move up a directory level
  365.  
  366. up_level:
  367.     mov    ah,3BH            ; change current directory
  368.     mov    dx,offset up_dir    ;   up a level
  369.     int    doscall            ;### error chk?
  370.     dec    level            ; adjust level count
  371.     dec    level            ;   by 2
  372.     ret
  373.  
  374.  
  375. ;**************************************************************
  376. ; get list of files that match
  377. ;    entry -        di = addr of place to put data
  378. ;    return -    di = addr of next data loc
  379. ;            ax = # files found (stored in tmp_cnt during routine)
  380.  
  381. get_file_names:
  382.     mov    tmp_loc,di
  383.     mov    tmp_cnt,0        ; init file cntr for this routine
  384.     push    di
  385.     set_dta fb_reserve        ; set data transfer area
  386.     mov    al,0            ; clear fb_pname area
  387.     mov    di,offset fb_pname
  388.     mov    cx,11
  389.     repz    stosb
  390.     pop    di
  391.     mov    ah,find_file        ; find match file
  392.     mov    dx,5DH            ; point at default fcb+1
  393.     mov    cx,010H            ; attributes to look for
  394.     int    doscall
  395.     jnc    sav_nam            ; if we found something
  396.     mov    ax,0            ; else
  397.     ret                ;    return with cnt=0
  398.  
  399. sav_nam:
  400.     cmp    fb_attr,10H        ; directory?
  401.     jne    no_save            ;   if not
  402.     cmp    fb_pname, '.'        ; named "."?
  403.     je    no_save            ;   if yes
  404.     mov    si,offset fb_pname    ; else save filename
  405.     mov    cx,11
  406.     repz    movsb
  407.     inc    tmp_cnt            ; bump file cnt
  408. no_save:
  409.     push    di
  410.     mov    al,0            ; clear fb_pname area
  411.     mov    di,offset fb_pname
  412.     mov    cx,13
  413.     repz    stosb
  414.     pop    di
  415.     mov    ah,find_nxt_file    ; find nxt file match
  416.     int    doscall
  417.     cmp    al,18            ; any file?
  418.     jnz    sav_nam            ;    yes
  419.     call    sort
  420.     mov    ax,tmp_cnt        ;    no, return  ax = tmp_cnt
  421.     ret
  422.  
  423.  
  424. ;**************************************************************
  425. ; sort list of files
  426. ;    entry -        di = nxt data loc
  427. ;            tmp_loc = start of data to sort
  428. ;            tmp_cnt = how many to sort
  429. ;    return -    di = nxt data loc
  430. ;            data area is sorted
  431.  
  432. sort:    push    di
  433.         cmp     tmp_cnt,1               ; more than one?
  434.     jnz    sort_start        ;    yes
  435.     jmp    sort_done        ;    no - only one
  436. sort_start:
  437.     mov    bx,tmp_loc
  438.     mov    dl,0
  439.     mov    dh,1
  440. sort1:    mov    si,bx
  441.     mov    di,si
  442.     add    di,11
  443.     mov    cx,8
  444.     repz    cmpsb
  445.     jle    sort3
  446.     mov    cx,11
  447.     mov    dl,1
  448.     mov    si,bx
  449.     mov    di,si
  450.     add    di,11
  451. sort2:    mov    al,[si]
  452.     xchg    [di],al
  453.     mov    [si],al
  454.     inc    si
  455.     inc    di
  456.     loop    sort2
  457. sort3:    add    bx,11
  458.     inc    dh
  459.     mov    al,dh            ;### expand to 16 bit cnt
  460.     xor    ah,ah
  461.     cmp    ax,tmp_cnt
  462.     jl    sort1
  463.     cmp    dl,1
  464.     jz    sort_start
  465. sort_done:
  466.     pop    di
  467.     ret
  468.  
  469. ;**************************************************************
  470. ; type cr, lf
  471. crlf:
  472.     display    crlf_msg
  473.     ret
  474.  
  475. ;**********************************
  476. ;***                ***
  477. ;***    Storage Allocation    ***
  478. ;***                ***
  479. ;**********************************
  480.  
  481. ;**************************************************************
  482. crlf_msg    db    CR, LF, "$"
  483. root_dir    db    "\",0
  484. up_dir          db      "..",0              ; go up a directory level
  485. dn_dir        db    ".\", 16 dup (?)
  486. old_dir         db      "\",  64 dup (?)    ; saves original directory
  487. no_label        db      "No DiskLabel$"
  488. no_subdirs      db      " No SubDirs$"
  489. sign_on         db      "Baum V1.2 ", FACE, "$"
  490. end_pad         db      (?)                 ; graphic joining character
  491. link            db      CR, LF, "    ", COR, "$"; link from disk name
  492. spaces8         db      "        $"         ; 8 spaces
  493. spaces1         db      " $"                ; 1 space
  494. tmp_cnt         dw      (?)                 ; temporary counter
  495. tmp_loc         dw      (?)                 ; tmp location storage
  496. unused          dw      -1                  ; # chars not used in field
  497.  
  498. ; 'level' is current directory level (0 = root), and is used as index into
  499. ; begin_dir, num_dir, and cur_dir arrays.  begin_dir array stores addresses
  500. ; in buf where the data for each level begins.  num_dir array stores the
  501. ; number of directories at each level.  cur_dir array stores the number
  502. ; of the directory being processed at each level.  Whenever we move up
  503. ; one level, the data for all lower levels is obsolete and the pointers
  504. ; are now invalid and the corresponding area in 'buf' may be re-used.
  505.  
  506. level           dw      (?)               ; current level ( 0 - ((n-1)*2) )
  507. begin_dir    dw    max_level dup (?) ; index within BUF where data starts
  508. num_dir        dw    max_level dup (?) ; # dirs at this level
  509. cur_dir        dw    max_level dup (?) ; # of dir being proc. at this level
  510.  
  511. ; CAUTION!!!  be careful when making modifications.
  512. ; The buffers from here on are used at different times and are overlapping.
  513. ; 'fcb' overlaps 'buffer', and 'buffer' overlaps 'fb_*' and 'buf'.
  514.  
  515. fcb    db    0FFH, 0,0,0,0,0,8, 0, "???????????"
  516. buffer        db    (?)
  517.  
  518. fb_reserve    db    21 dup (?)    ; data returned about file
  519. fb_attr        db    ?
  520. fb_time        dw    ?
  521. fb_date        dw    ?
  522. fb_size_lo    dw    ?
  523. fb_size_hi    dw    ?
  524. fb_pname    db    13 dup (?)
  525.  
  526. buf:        db    (?)        ; buffer area from here to stack
  527.                     ; stores sorted directories for
  528.                     ; all levels
  529.  
  530. prognam    ends        ;end of code segment
  531.     end  start    ;end assembly
  532.  
  533.  
  534.